from django.conf import settings
from django.core.cache import cache
# 分类筛选：django-filter：filter_backends配置DjangoFilterBackend，再在filter_fields中配置分组筛选的字段
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.generics import ListAPIView
from rest_framework.views import APIView, Response

from celery_task import update_video_heat, update_video_search
from utils.common import check_vip_exp
from utils.response import APIResponse
from . import models, serializers

'''群查分类'''
class CategoryListAPIView(ListAPIView):
    queryset = models.Category.objects.filter(is_show=True).order_by('order').all()
    serializer_class = serializers.CategoryModelSerializer


'''群查地区'''
class RegionListAPIView(ListAPIView):
    queryset = models.Region.objects.filter(is_show=True).order_by('order').all()
    serializer_class = serializers.RegionModelSerializer


'''群查类型'''
class TypeListAPIView(ListAPIView):
    queryset = models.Type.objects.filter(is_show=True).order_by('order').all()
    serializer_class = serializers.TypeModelSerializer


'''群查年份'''
class PeriodListAPIView(ListAPIView):
    queryset = models.Period.objects.filter(is_show=True).order_by('-order').all()
    serializer_class = serializers.PeriodModelSerializer


'''获取视频信息接口'''
class VideoListAPIView(ListAPIView):
    queryset = models.Video.objects.filter(is_show=True).order_by("-order").all()
    serializer_class = serializers.VideoModelSerializer

    filter_backends = [DjangoFilterBackend, OrderingFilter, SearchFilter]  # 配置DjangoFilterBackend

    # 参与搜索的字段: search=python  (name字段中带python就ok)
    search_fields = ['title', "desc"]

    # 参与排序的字段: ordering=-price,id,students
    ordering_fields = ['order', 'score', 'heat', "pub_time"]

    # 参与分类筛选的字段： 外键字段会默认连表，帮你查询第三张表
    filter_fields = ['category', "region", "period", "type", "is_free", "credits"]

    def get(self, request, *args, **kwargs):
        objs = super().list(request, *args, **kwargs)
        if objs:
            # 提交异步任务，更新搜索
            result = update_video_search.delay(objs.data)
            print(result, "更新搜索数")  # id号
        return objs


'''获取视频剧集接口'''
class VideoSectionAPIView(APIView):
    def post(self, request, *args, **kwargs):
        section_pk_list = []

        # 根据视频主键更新热度
        pk = kwargs.get("pk")
        if pk:
            # 提交异步任务，更新热度
            result = update_video_heat.delay(pk)
            print(result, "更新热度")  # id号

        # 根据剧集主键拿到视频
        section_pk = request.data.get("pk")
        # 获取多个剧集主键
        if not section_pk:
            section_pk_list = models.Video.objects.filter(pk=pk).values_list("video_section__v_id").order_by(
                "video_section__order")
            if section_pk_list:
                section_pk = section_pk_list[0][0]  # 列表套元祖

        # 得到剧集主键,去数据库中查数据
        section_obj = models.Video_Section.objects.filter(is_show=True, pk=section_pk).first()

        '''根据视频类型和用户类型来判断是否可以观看该视频'''
        # 先查看视频是否免费
        if not section_obj.video.is_free:
            # 判断登陆
            if request.user.is_authenticated:
                '''检测VIP是否过期'''
                check_vip_exp(request.user)
                # 如果登陆了但不是会员
                if request.user.vip_type == 0:
                    # 判断该视频发布的剧集数
                    if section_obj.video.pub_sections > 1:
                        # 查看剧集主键列表是否存在
                        if not section_pk_list:
                            section_pk_list = models.Video_Section.objects.filter(video=section_obj.video).values_list(
                                "v_id").order_by("order")
                            print(section_pk_list)
                        # 如果没有不是第第一集就不给你看
                        if section_pk != section_pk_list[0][0]:
                            return APIResponse(1, "error", "试看结束，请开通VIP会员继续观看")
                        else:
                            pass
                    else:
                        # 就一集，不给看
                        return APIResponse(1, "error", "开通VIP会员抢先观看")
                else:
                    pass
            else:
                # 没有登陆不给看
                return APIResponse(1, "error", "观看会员视频，请先登录")

        # 得到序列化后的数据
        response = Response(serializers.VideoSectionModelSerializer(section_obj, many=False).data)
        if request.user.is_authenticated:
            record_obj = models.Record.objects.filter(
                user=request.user,
                video_section_id=section_pk
            ).first()
            if record_obj:
                response.data["play_time"] = record_obj.play_time
            else:
                response.data["play_time"] = 0
        else:
            response.data["play_time"] = 0
        return response


'''获取排行榜接口'''
class LeaderboardAPIView(APIView):
    def post(self, request, *args, **kwargs):
        data = request.data
        rank = data.get("rank")
        if rank == "heat":
            '''查询缓存，缓存没有就自己走数据库'''
            heat_list = cache.get('heat_list')
            if not heat_list:
                print("走数据库")
                queryset = models.Video.objects.filter(is_show=True).order_by("-heat").all()[:settings.RANKING_COUNT]
                response = Response(serializers.LeaderboardSerializer(queryset, many=True).data)
                cache.set('heat_list', response.data)  # 缓存不设过期时间，更新任务交给celery异步任务框架
                return response
            return Response(heat_list)
        elif rank == "search":
            '''查询缓存，缓存没有就自己走数据库'''
            search_list = cache.get('search_list')
            if not search_list:
                print("走数据库")
                queryset = models.Video.objects.filter(is_show=True).order_by("-search").all()[:settings.RANKING_COUNT]
                response = Response(serializers.LeaderboardSerializer(queryset, many=True).data)
                cache.set('search_list', response.data)  # 缓存不设过期时间，更新任务交给celery异步任务框架
                return response
            return Response(search_list)
        return APIResponse(1, "error")


'''获取VIP视频接口'''
class VipVideoListAPIView(ListAPIView):
    queryset = models.Video.objects.filter(is_show=True, is_free=False).order_by("-order").all()
    serializer_class = serializers.VideoModelSerializer
    # 配置排序
    filter_backends = [OrderingFilter]
    # 参与排序的字段: ordering=-price,id,students
    ordering_fields = ['order', 'score', 'heat', "pub_time"]


'''保存播放视频记录接口'''
class SaveRecordAPIView(APIView):
    def post(self, request, *args, **kwargs):
        if request.user.is_authenticated:
            print("已登录")
            data = request.data
            obj = models.Record.objects.filter(
                user=request.user,
                video_section_id=data.get("section_id")
            ).first()
            # 如果有记录
            if not obj:
                models.Record.objects.create(
                    user=request.user,
                    video_section_id=data.get("section_id"),
                    play_time=data.get("play_time")
                )
            else:
                # 如果没有记录。就判断播放时间然后取更新
                if data.get("play_time") > obj.play_time:
                    obj.play_time = data.get("play_time")
                    obj.save()

            return APIResponse(0, "info", "已登录")
        return APIResponse(1, "info", "未登录")


